/**
 *
 */
package de.cbf.cam.dsa.person.base;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

import de.cbf.util.entities.FloatString;

/**
 * @author Surfer
 *
 */
public class CompositePersonBaseDSA extends Composite {
	public static final Log logger = LogFactory.getLog(CompositePersonBaseDSA.class);

	protected final NumberFormat format = NumberFormat.getNumberInstance();

	public static final String COMPOSITE_ID = "CompositePersonBaseDSA";

	public static final String COMMAND_SELECTION = "selection";//TODO move constants to interface for all composites
	public static final String COMMAND_MODIFY	 = "modify";
	public static final String COMMAND_UNKNOWN 	 = null;
	//TODO move IDs to specific interface for Composite, specify add/remove listeners
	public static final int ID_UNKNOWN 				= -1;
	public static final int ID_TITLE 				=  0;
	public static final int ID_FIRST_NAME 			=  1;
	public static final int ID_NAME_ADD				=  2;
	public static final int ID_SUR_NAME 			=  3;
	public static final int ID_CHARACTER_SPECIALS	=  4;
	public static final int ID_LOOKS 				=  5;
	public static final int ID_HEIGTH 				=  6;
	public static final int ID_WEIGHT 				=  7;
	public static final int ID_BIRTH_DAY 			=  8;
	public static final int ID_BIRTH_MONTH 			=  9;
	public static final int ID_BIRTH_YEAR 			= 10;
	public static final int ID_RACE 				= 11;
	public static final int ID_CULTURE 				= 12;
	public static final int ID_PROFESSION 			= 13;
	public static final int ID_EYES 				= 14;
	public static final int ID_HAIR 				= 15;

	public static final String UI_ID_TXT_FIRST_NAME		= COMPOSITE_ID+".FIRST_NAME";
	public static final String UI_ID_TXT_SUR_NAME		= COMPOSITE_ID+".SUR_NAME";
	public static final String UI_ID_TXT_NAME_ADD		= COMPOSITE_ID+".NAME_ADD";
	public static final String UI_ID_TXT_TITLE			= COMPOSITE_ID+".TITLE";
	public static final String UI_ID_TXT_CHAR_SPECIALS	= COMPOSITE_ID+".CHAR_SPECIALS";
	public static final String UI_ID_TXT_LOOKS			= COMPOSITE_ID+".LOOKS";
	public static final String UI_ID_TXT_BIRTH_YEAR		= COMPOSITE_ID+".BIRTH_YEAR";
	public static final String UI_ID_CMB_BIRTH_MONTH	= COMPOSITE_ID+".BIRTH_MONTH";
	public static final String UI_ID_CMB_BIRTH_DAY		= COMPOSITE_ID+".BIRTH_DAY";
	public static final String UI_ID_TXT_HEIGTH			= COMPOSITE_ID+".HEIGTH";
	public static final String UI_ID_TXT_WEIGHT			= COMPOSITE_ID+".WEIGHT";
	public static final String UI_ID_CMB_RACE			= COMPOSITE_ID+".RACE";
	public static final String UI_ID_CMB_CULTURE		= COMPOSITE_ID+".CULTURE";
	public static final String UI_ID_CMB_PROFESSION		= COMPOSITE_ID+".PROFESSION";

	private Text txtFirstName;
	private Text txtSurName;
	private Text txtNameAdd;
	private Text txtTitle;
	private Text txtCharacterSpecials;
	private Text txtLooks;
	private Text txtBirthYear;
	private Text txtHeight;
	private Text txtWeight;

	private Combo cbBirthDay;
	private Combo cbBirthMonth;
	private Combo cbRace;
	private Combo cbCulture;
	private Combo cbProfession;


	/**
	 * @param parent
	 * @param style
	 */
	public CompositePersonBaseDSA(Composite parent, int style) {
		super(parent, style);
		setLayout(new GridLayout(4, false));

		Label lblTitle = new Label(this, SWT.NONE);
		lblTitle.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblTitle.setText("Titel:");

		txtTitle = new Text(this, SWT.BORDER);
		txtTitle.setText("Title");
		txtTitle.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label lblFirstName = new Label(this, SWT.NONE);
		lblFirstName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblFirstName.setText("Vorname:");

		txtFirstName = new Text(this, SWT.BORDER);
		txtFirstName.setText("FirstName");
		txtFirstName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label lblNameAdd = new Label(this, SWT.NONE);
		lblNameAdd.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblNameAdd.setText("Namenszusatz");

		txtNameAdd = new Text(this, SWT.BORDER);
		txtNameAdd.setText("NameAdd");
		txtNameAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label lblSurName = new Label(this, SWT.NONE);
		lblSurName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblSurName.setText("Nachname:");

		txtSurName = new Text(this, SWT.BORDER);
		txtSurName.setText("SurName");
		txtSurName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label lblEndname = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		lblEndname.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 4, 1));
		lblEndname.setText("endName");

		Label lblRace = new Label(this, SWT.NONE);
		lblRace.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblRace.setText("Rasse:");

		cbRace = new Combo(this, SWT.READ_ONLY);
		cbRace.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label lblCulture = new Label(this, SWT.NONE);
		lblCulture.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblCulture.setText("Kultur:");

		cbCulture = new Combo(this, SWT.READ_ONLY);
		cbCulture.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 3, 1));

		Label lblProfession = new Label(this, SWT.NONE);
		lblProfession.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblProfession.setText("Profession");

		cbProfession = new Combo(this, SWT.READ_ONLY);
		cbProfession.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));

		Label lblSeprace = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		lblSeprace.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 4, 1));
		lblSeprace.setText("SepRace");

		Label lblBirthDay = new Label(this, SWT.NONE);
		lblBirthDay.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblBirthDay.setText("Geburtstag:");

		cbBirthDay = new Combo(this, SWT.READ_ONLY);
		GridData gd_cbBirthDay = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_cbBirthDay.widthHint = 20;
		cbBirthDay.setLayoutData(gd_cbBirthDay);

		cbBirthMonth = new Combo(this, SWT.READ_ONLY);
		cbBirthMonth.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		txtBirthYear = new Text(this, SWT.BORDER);
		txtBirthYear.setText("BirthYear");
		GridData gd_txtBirthYear = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_txtBirthYear.widthHint = 50;
		txtBirthYear.setLayoutData(gd_txtBirthYear);

		Label lblHeight = new Label(this, SWT.NONE);
		lblHeight.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblHeight.setText("Height:");

		txtHeight = new Text(this, SWT.BORDER);
		GridData gd_txtHeight = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_txtHeight.widthHint = 20;
		txtHeight.setLayoutData(gd_txtHeight);

		Label lblWeight = new Label(this, SWT.NONE);
		lblWeight.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblWeight.setText("Weight:");

		txtWeight = new Text(this, SWT.BORDER);
		txtWeight.setText("Weight");
		txtWeight.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		Label lblLooks = new Label(this, SWT.NONE);
		GridData gd_lblLooks = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1);
		gd_lblLooks.verticalIndent = 3;
		lblLooks.setLayoutData(gd_lblLooks);
		lblLooks.setText("Aussehen:");

		txtLooks = new Text(this, SWT.BORDER);
		txtLooks.setText("Looks");
		GridData gd_txtLooks = new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1);
		gd_txtLooks.heightHint = 30;
		txtLooks.setLayoutData(gd_txtLooks);

		Label lblCharacterspecials = new Label(this, SWT.NONE);
		GridData gd_lblCharacterspecials = new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1);
		gd_lblCharacterspecials.verticalIndent = 3;
		lblCharacterspecials.setLayoutData(gd_lblCharacterspecials);
		lblCharacterspecials.setText("Eigenschaften:");

		txtCharacterSpecials = new Text(this, SWT.BORDER);
		txtCharacterSpecials.setText("CharacterSpecials");
		GridData gd_txtCharacterspecials = new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1);
		gd_txtCharacterspecials.heightHint = 30;
		txtCharacterSpecials.setLayoutData(gd_txtCharacterspecials);
	}

	protected List<ActionListener> listeners = new ArrayList<ActionListener>();
	/**
	 * Listener will act on
	 * <li>id = ID_ (property)
	 * <li>command = COMMAND_ (eventType)
	 * @param listener
	 * @return
	 */
	public boolean addUIListener(ActionListener listener){
		return listeners.add(listener);
	}

	public boolean removeUIListener(ActionListener listener){
		return listeners.remove(listener);
	}

	protected void issueUIEvent(int id, String command){
		ActionEvent event = new ActionEvent(this, id, command);
		for (ActionListener listener : listeners) {
			listener.actionPerformed(event);
		}
	}


	public String getFirstName(){
		return txtFirstName.getText();
	}

	public void setFirstName(String value){
		Cursor cursor = txtFirstName.getCursor();
		txtFirstName.setText(value);
		txtFirstName.setCursor(cursor);
	}

	public String getSurName(){
		return txtSurName.getText();
	}

	public void setSurName(String value){
		Cursor cursor = txtSurName.getCursor();
		txtSurName.setText(value);
		txtSurName.setCursor(cursor);
	}

	public String getNameAdd(){
		return txtNameAdd.getText();
	}

	public void setNameAdd(String value){
		Cursor cursor = txtNameAdd.getCursor();
		txtNameAdd.setText(value);
		txtNameAdd.setCursor(cursor);
	}

	public String getTitle(){
		return txtTitle.getText();
	}

	public void setTitle(String value){
		Cursor cursor = txtTitle.getCursor();
		txtTitle.setText(value);
		txtTitle.setCursor(cursor);
	}

	public String getLooks(){
		return txtLooks.getText();
	}

	public void setLooks(String value){
		Cursor cursor = txtLooks.getCursor();
		txtLooks.setText(value);
		txtLooks.setCursor(cursor);
	}

	public String getCharacterSpecials(){
		return txtCharacterSpecials.getText();
	}

	public void setCharacterSpecials(String value){
		Cursor cursor = txtCharacterSpecials.getCursor();
		txtCharacterSpecials.setText(value);
		txtCharacterSpecials.setCursor(cursor);
	}

	public String getHeigth(){
		return txtHeight.getText();
	}

	public void setHeigth(String value){
		Cursor cursor = txtHeight.getCursor();
		txtHeight.setText(value);
		txtHeight.setCursor(cursor);
	}

	public String getWeight(){
		return txtWeight.getText();
	}

	public void setWeight(String value){
		Cursor cursor = txtWeight.getCursor();
		txtWeight.setText(value);
		txtWeight.setCursor(cursor);
	}

	public String getBirthYear(){
		return txtBirthYear.getText();
	}

	public void setBirthYear(String value){
		Cursor cursor = txtBirthYear.getCursor();
		txtBirthYear.setText(value);
		txtBirthYear.setCursor(cursor);
	}


	public Integer getSelectedBirthDay(){
		return cbBirthDay.getSelectionIndex();
	}
	public void setSelectedBirthDay(Integer value){
		if (value instanceof Integer) {
			Integer index = (Integer) value;
			if(index < cbBirthDay.getItemCount()){
				cbBirthDay.setSelection(new Point(index,index));
			}else{
				logger.error("Index not available: "+index);
			}
		}else{
			logger.error("wrong type for birthDay: "+value.getClass().getCanonicalName());
		}
	}
	public void setAmmountOfPossibleBirthdays(int ammount){
		for (int i = 0; i < ammount; i++) {
			cbBirthDay.add(i+1+"");
		}
	}

	public String getSelectedMonth(){
		return cbBirthMonth.getText();
	}
	public void setSelectedMonth(String value){
		for (int i = 0; i < cbBirthMonth.getItems().length; i++) {
			if(cbBirthMonth.getItem(i).equals(value)){
				cbBirthMonth.select(i);
			}
		}
		logger.error(value+" is not selectable in BirthMonths");
	}
	public void setPossibleMonths(List<String> months){
		String[] monthArray = months.toArray(new String[months.size()]);
		cbBirthMonth.setItems(monthArray);
	}

	public String getSelectedRace(){
		return cbRace.getText();
	}

	public void setSelectedRace(String raceName){
		for (int i = 0; i < cbRace.getItems().length; i++) {
			if(cbRace.getItem(i).equals(raceName)){
				cbRace.select(i);
			}
		}
		logger.error(raceName+" is not selectable in races");
	}

	public void setPossibleRaces(List<FloatString> races){
		String [] raceArray = races.toArray(new String[0]);
		cbRace.setItems(raceArray);
	}

	public String getSelectedCulture(){
		String key = cbCulture.getText();
		return key;
	}
	public void setSelectedCulture(String value){
		for (int i = 0; i < cbCulture.getItems().length; i++) {
			if(cbCulture.getItem(i).equals(value)){
				cbCulture.select(i);
			}
		}
		logger.error(value+" is not selectable in cbCultures");
	}

	public void setPossibleCultures(List<FloatString> cultures){
		for (FloatString item : cultures) {
			cbCulture.add(item.getText());
		}
	}


	public String getSelectedProfession(){
		return cbProfession.getText();
	}
	public void setSelectedProfession(String value){
		for (int i = 0; i < cbProfession.getItems().length; i++) {
				if(cbProfession.getItem(i).equals(value)){
					cbProfession.select(i);
				}
			}
			logger.error(value+" is not selectable in professions");
		}
	public void setPossibleProfessions(List<FloatString> possibleProfessions){
		String[] professions = possibleProfessions.toArray(new String[0]);
		cbProfession.setItems(professions);
	}

	protected class UIPropagationListener implements Listener{
		@Override
		public void handleEvent(Event event) {
			String command = findCommandByType(event.type);
			int property = findPropertyByWidget(event.widget);
			issueUIEvent(property, command);
		}

		private int findPropertyByWidget(Widget widget) {
			//use object comparison, equals would only possibly work, not sure
			if(widget == txtTitle ){
				return ID_TITLE;
			}
			if(widget == txtFirstName ){
				return ID_FIRST_NAME;
			}
			if(widget == txtNameAdd ){
				return ID_NAME_ADD;
			}
			if(widget == txtSurName ){
				return ID_SUR_NAME;
			}
			if(widget == txtCharacterSpecials ){
				return ID_CHARACTER_SPECIALS;
			}
			if(widget == txtLooks ){
				return ID_LOOKS;
			}
			if(widget == txtHeight ){
				return ID_HEIGTH;
			}
			if(widget == txtWeight ){
				return ID_WEIGHT;
			}
			if(widget == cbBirthDay ){
				return ID_BIRTH_DAY;
			}
			if(widget == cbBirthMonth ){
				return ID_BIRTH_MONTH;
			}
			if(widget == txtBirthYear ){
				return ID_BIRTH_YEAR;
			}
			if(widget == cbRace ){
				return ID_RACE;
			}
			if(widget == cbCulture ){
				return ID_CULTURE;
			}
			if(widget == cbProfession ){
				return ID_PROFESSION;
			}
			return ID_UNKNOWN;
		}

		private String findCommandByType(int type) {
			switch (type) {
			case SWT.Selection:
				return COMMAND_SELECTION;
			case SWT.Modify:
				return COMMAND_MODIFY;
			default:
				return COMMAND_UNKNOWN;
			}
		}
	}
}
